package top.lixunda.ecommerce.server.auth.feign;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import top.lixunda.common.utils.ObjectValidators;
import top.lixunda.ecommerce.server.auth.api.entity.cache.CacheAuthCode;
import top.lixunda.ecommerce.server.auth.api.entity.dto.EmailGeneralCodeDTO;
import top.lixunda.ecommerce.server.auth.api.entity.dto.EmailNormalDTO;
import top.lixunda.ecommerce.server.auth.api.constants.TemplateEmailIds;
import top.lixunda.ecommerce.server.auth.api.feign.IFeignEmailAuthCode;
import top.lixunda.ecommerce.server.auth.service.IEmailSenderService;
import top.lixunda.commerce.common.core.entity.MessageObject;
import top.lixunda.commerce.common.core.exception.InternalApiException;
import top.lixunda.common.validate.XumValid;
import top.lixunda.ecommerce.server.business.BaseController;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Xumda
 * @version time:2019/11/25 9:38
 * <p>
 * 发送邮件的controller
 */
@RestController
@Slf4j
public class FeignEmailAuthCodeController extends BaseController
        implements IFeignEmailAuthCode {

    private final IEmailSenderService emailSender;

    private volatile Map<String, String> templates = new ConcurrentHashMap<>(4);

    private static final Map<String, String> TEMPLATE_MAPPING = new HashMap<>();

    @Autowired
    public FeignEmailAuthCodeController(IEmailSenderService emailSender) {
        this.emailSender = emailSender;
        TEMPLATE_MAPPING.put(TemplateEmailIds.KEY_GENERAL_CODE, "template/GeneralCodeTemplate.html");
    }

    /**
     * 获取模板，本地map进行缓存
     *
     * @param templateName 模板名称
     * @return 返回模板内容
     */
    @SuppressWarnings("SameParameterValue")
    private String getContentTemplate(final String templateName) {
        if (templates.get(templateName) == null) {
            synchronized (FeignEmailAuthCodeController.class) {
                if (templates.get(templateName) == null) {
                    StringBuilder builder = new StringBuilder();
                    try (InputStream inputStream = Thread.currentThread().getContextClassLoader()
                            .getResourceAsStream(TEMPLATE_MAPPING.get(templateName));
                         BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
                        String line;
                        while ((line = reader.readLine()) != null) {
                            builder.append(line);
                        }
                    } catch (IOException e) {
                        throw new InternalApiException("读取模板内容异常");
                    }
                    templates.put(templateName, builder.toString().trim());
                }
            }
        }
        return templates.get(templateName);
    }

    /**
     * 发送通用消息
     *
     * @param emailNormalDTO EmailNormalDTO
     * @return CacheAuthCode
     */
    @Override
    public MessageObject<Boolean> sendMessage(@XumValid EmailNormalDTO emailNormalDTO) {
        boolean success = emailSender.sendEmail(emailNormalDTO.getAccounts(), emailNormalDTO.getTitle(),
                emailNormalDTO.getContent());
        if (!success) {
            throw new InternalApiException("发送验证码失败");
        }
        return MessageObject.success("发送成功", true);
    }

    /**
     * 发送自定义信息，批量
     *
     * @param list EmailNormalDTO信息，批量
     * @return CacheAuthCode
     */
    @Override
    public MessageObject<Boolean> sendMessageList(List<EmailNormalDTO> list) {
        if (ObjectValidators.isEmpty(list)) {
            throw getAppException("发送邮件参数不能为空!");
        }
        list.forEach(this::sendMessage);
        return MessageObject.success("发送成功", true);
    }

    /**
     * 发送通用验证码消息
     * 模板名称 KEY_GENERAL
     *
     * @param emailGeneralCodeDTO CacheAuthCode
     * @return CacheAuthCode
     * @see TemplateEmailIds#KEY_GENERAL_CODE
     */
    @Override
    public CacheAuthCode sendGeneralCodeMessage(@XumValid EmailGeneralCodeDTO emailGeneralCodeDTO) {
        String content = getContentTemplate(TemplateEmailIds.KEY_GENERAL_CODE);
        content = content.replace("{{action}}", emailGeneralCodeDTO.getAction())
                .replace("{{time}}", String.valueOf(emailGeneralCodeDTO.getTime()))
                .replace("{{code}}", emailGeneralCodeDTO.getCode());

        boolean success = emailSender.sendEmail(Collections.singletonList(emailGeneralCodeDTO.getEmail()),
                emailGeneralCodeDTO.getAction() + "验证码", content);
        if (!success) {
            throw new InternalApiException("发送验证码失败");
        }
        return emailGeneralCodeDTO.toAuthCodeCache();
    }
}
